﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

public class Characters
{
    public enum States
    {
        Alive,
        TakingDamage,
        Dead
    };

    protected SpriteEffects flip = SpriteEffects.None;

    protected Animation idleAnimation;
    protected Animation walkingAnimation;
    protected Animation barrelAnimation;
    protected Animation barrelRollingAnimation;
    protected Animation barrelThrowingAnimation;
    protected Animation hitAnimation;
    protected Animation dyingAnimation;
    protected AnimationPlayer sprite;

    protected Texture2D testCollider;

    protected string tankingDamageSound;

    private int takingDamageTime = 0;
    private int blinkingTime = 0;

    public int Life
    {
        get { return life; }
        set { life = value; }
    }
    private int life;

    public States State
    {
        get { return state; }
        //set { state = value; }
    }
    private States state;

    public Direction _Direction
    {
        get { return direction; }
        set { direction = value; }
    }
    private Direction direction;

    public Barrel _Barrel
    {
        get { return barrel; }
        set { barrel = value; }
    }
    private Barrel barrel;

    public bool HasBarrel
    {
        get { return hasBarrel; }
        set { hasBarrel = value; }
    }
    private bool hasBarrel;

    // Physics state
    protected float Speed
    {
        get { return speed; }
        set { speed = value; }
    }
    private float speed;

    protected float Friction
    {
        get { return friction; }
        set { friction = value; }
    }
    private float friction;

    protected Vector2 position;
    public Vector2 Position
    {
        get 
        {
            return position; 
        }
        set 
        {
            //Console.WriteLine(position.Y + " " + value.Y);
            position = value; 
        }
    }

    protected Vector2 Velocity;


    protected Rectangle localBounds;
    /// <summary>
    /// Gets a rectangle which bounds this character in world space.
    /// </summary>
    public Rectangle BoundingRectangle
    {
        get
        {
            int left = (int)Math.Round(Position.X - sprite.Origin.X) + localBounds.X;
            int top = (int)Math.Round(Position.Y - sprite.Origin.Y) + localBounds.Y;

            return new Rectangle(left, top, localBounds.Width, localBounds.Height);
        }
    }

    public Characters(float speed, float friction, Vector2 position)
    {
        state = States.Alive;
        Speed = speed;
        Friction = friction;
        Position = position;
        hasBarrel = false;
    }

    public virtual void TakeDamage(int damage)
    {
        if (State == States.Alive)
        {
            Life -= damage;
            state = Life <= 0 ? States.Dead : States.TakingDamage;

            AudioManager.PlaySound(tankingDamageSound);

            if (hasBarrel)
            {
                GameSession.BarrelsList.Remove(barrel);
                hasBarrel = false;
                barrel = null;
            }
        }
    }

    /// <summary>
    /// Loads the character sprite sheet and sounds.
    /// </summary>
    public virtual void LoadContent(ContentManager content) { }

    /// <summary>
    /// Handles input, performs physics, and animates the player sprite.
    /// </summary>
    public virtual void Update(GameTime gameTime)
    {
        switch (State)
        {
            case States.Alive:

                if (Velocity.Length() - 0.25f > 0)
                {
                    if (Math.Abs(Velocity.X) >= Math.Abs(Velocity.Y))
                    {
                        direction = Velocity.X > 0 ? Direction.Right : Direction.Left;
                    }
                    else
                    {
                        direction = Velocity.Y > 0 ? Direction.Down : Direction.Up;
                    }

                    if (!hasBarrel)
                    {
                        sprite.PlayAnimation(walkingAnimation);
                    }
                    else
                    {
                        sprite.PlayAnimation(barrelRollingAnimation);
                    }
                }
                else
                {
                    if (!hasBarrel)
                    {
                        sprite.PlayAnimation(idleAnimation);
                    }
                    else
                    {
                        sprite.PlayAnimation(barrelAnimation);
                    }
                }
                break;
            case States.Dead:
                sprite.PlayAnimation(dyingAnimation);
                break;
            case States.TakingDamage:
                sprite.PlayAnimation(hitAnimation);
                takingDamageTime += gameTime.ElapsedGameTime.Milliseconds;
                if (takingDamageTime > 2000)
                {
                    state = States.Alive;
                    takingDamageTime = 0;
                }
                break;
        }
        
        if (hasBarrel)
        {
            _Barrel.Position.X = Position.X - 30;
            _Barrel.Position.Y = Position.Y - 130;
        }

        if (position.X > 1270)
        {
            position.X = 1270;
            Velocity.X = 0;
        }
        else
            if (position.X < 10)
            {
                position.X = 10;
                Velocity.X = 0;
            }

        if (position.Y > 710)
        {
            position.Y = 710;
            Velocity.Y = 0;
        }
        else
            if (position.Y < 10)
            {
                position.Y = 10;
                Velocity.Y = 0;
            }
    }

    /// <summary>
    /// Updates the character's velocity and position.
    /// </summary>
    protected virtual void ApplyPhysics(/*GameTime gameTime*/ bool checkall)
    {
        //Vector2 previousPosition = Position;

        // Apply velocity and friction.
        Position += Velocity;
        Velocity *= Friction;
    }

    /// <summary>
    /// Draws animated characters.
    /// </summary>
    public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
    {
        // Flip the sprite to face the way we are moving.
        if (Velocity.X > 0)
            flip = SpriteEffects.FlipHorizontally;
        else if (Velocity.X < 0)
            flip = SpriteEffects.None;

        // Draw that sprite.
        if (state == States.TakingDamage)
        {
            blinkingTime += gameTime.ElapsedGameTime.Milliseconds;
            if (blinkingTime > 400)
            {
                blinkingTime = 0;
            }
            if (blinkingTime > 200)
            {
                return;
            }
        }

        sprite.Draw(gameTime, spriteBatch, new Vector2(Position.X, Position.Y + GameSession.screenAdjustment), flip);

        //Test Bounding Size
        //spriteBatch.Draw(testCollider, new Vector2(BoundingRectangle.X, BoundingRectangle.Y + GameSession.screenAdjustment),
        //  new Rectangle(0, 0, BoundingRectangle.Width, BoundingRectangle.Height), Color.White);
    }
}